﻿using MD5Hash;
using MediatR;
using Microsoft.IdentityModel.Tokens;
using SmartTracking.API.Read.Application.Commands.User_command;
using SmartTracking.API.Read.DTO;
using SmartTracking.Domain.UserInfo;
using SmartTracking.ErrorCode;
using SmartTracking.Infrastructure.Interfaces;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace SmartTracking.API.Read.Application.CommandHandlers.User_handler
{
    public class LoginCommandHandler:IRequestHandler<LoginCommand,ApiResult<UserRoleDto>>
    {
        private readonly IBaseRepository<Users> userRep;
        private readonly IBaseRepository<Roles> roleRep;
        private readonly IBaseRepository<UserRoleMiddle> urRep;

        public LoginCommandHandler(
            IBaseRepository<Users> userRep,
            IBaseRepository<Roles> roleRep,
            IBaseRepository<UserRoleMiddle> urRep)
        {
            this.userRep = userRep;
            this.roleRep = roleRep;
            this.urRep = urRep;
        }

        public Task<ApiResult<UserRoleDto>> Handle(LoginCommand request, CancellationToken cancellationToken)
        {
            ApiResult<UserRoleDto> result = new ApiResult<UserRoleDto>();
            result.Code = ApiEnum.登录成功;
            result.Message = ApiEnum.登录成功.ToString();

            try
            {
                request.Password = request.Password.GetMD5();
                var list = from a in userRep.GetAll()
                           join b in urRep.GetAll()
                           on a.UserId equals b.UserId
                           join c in roleRep.GetAll()
                           on b.RoleId equals c.RoleId
                           where a.UserName == request.UserName
                           select new UserRoleDto
                           {
                               UserId = a.UserId,
                               UserNo = a.UserNo,
                               UserNickName = a.UserNickName,
                               UserName = a.UserName,
                               Password = a.Password,
                               UserSex = a.UserSex,
                               UserPhone = a.UserPhone,
                               UserEmail = a.UserEmail,
                               Address = a.Address,
                               DocumentTypeId = a.DocumentTypeId,
                               UserStatus = a.UserStatus,
                               URId = b.URId,
                               RoleId = b.RoleId,
                               RoleName = c.RoleName
                           };
                var entity = list.FirstOrDefault();

                if (entity == null)
                {
                    throw new Exception(ApiEnum.用户不存在.ToString());
                }
                if (entity.Password != request.Password)
                {
                    throw new Exception(ApiEnum.密码错误.ToString());
                }
                entity.Token = CreateTokenString(entity);
                result.data = entity;
            }
            catch (Exception ex)
            {
                result.Code = ApiEnum.登录失败;
                result.Message = ApiEnum.登录失败.ToString()+"," + ex.Message;
            }

            return Task.FromResult(result);
        }
        /// <summary>/// 生成 JWT Token（令牌）/// </summary>/// <returns></returns>
        private string CreateTokenString(UserRoleDto dto)
        {
            //私钥
            var secretByte = Encoding.UTF8.GetBytes("kdsfldsflkdslkflkdsflkdslfdslkflk");
            // 非对称加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            // 使用256 生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            var claim = new Claim[]
            {
                new Claim("UserId",dto.UserId.ToString()),
                new Claim("UserName",dto.UserName),
                new Claim("UserNickName",dto.UserNickName),
                new Claim("RoleId",dto.RoleId.ToString()),
                new Claim("RoleName",dto.RoleName),
                new Claim("UserNo",dto.UserNo),
            };
            // 生成Token
            var token = new JwtSecurityToken(
                issuer: "BeiJingBW",
                audience: "BeiJingBW",
                claims: claim,
                expires: DateTime.Now.AddDays(1), // 一天后过期
                signingCredentials: signingCredentials
            );
            // 生成token 字符串
            var strToken = new JwtSecurityTokenHandler().WriteToken(token);
            return strToken;
        }
    }
}
